package main

import (
    _config "./config"
    "./manager"
    "./tools/paths"
    "./tools/shell/console"
    "./tools/zip"
    "flag"
    . "fmt"
    "io/ioutil"
    "net"
    "path"
    "path/filepath"
    "strings"
)

var (
    productDir  string //工程文件夹
    section     string //目标机器
    host        string //目标IP
    initDir     string //需要初始化的工程文件夹
    initMode    string //初始化工程(模式)
    profile     _config.IniFile
    affirm      bool
    sudo        bool
    dependencie bool
    version1    bool
    version2    bool
    versionCode = "V0.6"
)

func init() {
    flag.StringVar(&productDir, "p", "", "工程目录")
    flag.StringVar(&section, "s", "", "使用的配置项(Section)")
    flag.StringVar(&host, "h", "", "目标服务器")
    flag.StringVar(&initDir, "init", "", "指定初始化工程目录")
    flag.StringVar(&initMode, "mode", "play", "初始化工程模式(默认并仅支持play)")
    flag.BoolVar(&affirm, "y", false, "无需确认信息")
    flag.BoolVar(&sudo, "sudo", false, "使用`sudo`启动")
    flag.BoolVar(&dependencie, "d", false, "启动前解决依赖关系")
    flag.BoolVar(&version1, "version", false, "查看版本信息")
    flag.BoolVar(&version2, "V", false, "查看版本信息")
    profile.Null = true
    zip.DO_LOG = false
}

func main() {
    flag.Parse()
    if version1 || version2 {
        versionInfo := `Deployment
version : %s
author  : Adinlead
`
        Printf(versionInfo, versionCode)
        return
    }
    if !sudo {
        for _, arg := range flag.Args() {
            if "-y" == arg {
                affirm = true
            } else if "--sudo" == arg {
                sudo = true
            }
        }
    }
    //Println("sudo   ---> ", sudo)
    //Println("affirm ---> ", affirm)
    //Println(flag.Args())
    //console.Clear()
    if initDir != "" {
        if paths.Exists(initDir) {
            if _config.InitFileTemplate[initMode] == "" {
                Printf("没有匹配的模式[initMode:%s]\n", initMode)
                return
            }
            publicIniFile := paths.Join(initDir, _config.ProfileName)
            nozipFile := paths.Join(initDir, _config.NozipFileName)
            if !paths.Exists(publicIniFile) || (paths.Exists(publicIniFile) && paths.IsFile(publicIniFile) &&
                (affirm || "Y" == strings.ToUpper(console.Input(Sprintf("工程配置文件[%s]已存在,是否覆盖? (Y/N)", publicIniFile))))) {
                if ioutil.WriteFile(publicIniFile, []byte(_config.InitFileTemplate[initMode]), 0644) == nil &&
                    ioutil.WriteFile(nozipFile, []byte(_config.NoZipFileTemplate[initMode]), 0644) == nil {

                    Println("初始化工程成功!")
                    return
                }
            } else {
                return
            }
        } else {
            Printf("工程[%s]不存在\n", initDir)
            return
        }
    }

    if productDir == "" && len(flag.Args()) > 0 {
        productDir = flag.Args()[0]
        if section == "" && host == "" && len(flag.Args()) > 1 {
            _tmp := flag.Args()[1]
            _ns, err := net.LookupHost(_tmp)
            if err != nil {
                section = _tmp
            } else {
                host = _ns[0]
            }
        }
    }
    var productProfile string
    if paths.Exists(productDir) {
        productProfile = paths.Join(productDir, _config.ProfileName)
        if !paths.Exists(productProfile) {
            Printf("工程[%s]未初始化,请使用 `-init %s [-mode MODE]`初始化工程\n", productDir, productDir)
            return
        }
        productDir, _ = filepath.Abs(productDir)
    } else {
        flag.Usage()
        Printf("Or Try : deployment [projectDir] [host/section]\n")
        return
    }
    var err error = nil
    if section != "" {
        profile, err = _config.NewIniFile(productProfile, section, "")
    } else if host != "" {
        profile, err = _config.NewIniFile(productProfile, "", host)
    } else {
        Println("请指定`section(-s)`或`host(-h)`")
        return
    }
    if err != nil {
        Printf("读取配置文件时发生错误错误:%s\n", err.Error())
        return
    }
    switch strings.ToLower(profile.Framework) {
    case "play":
        play := manager.Play{ProjectDir: productDir, Profile: profile, ProjectName: path.Base(productDir), Affirm: affirm, Sudo: sudo}
        play.DoPublic()
        break
    default:
        Printf("没有此框架[%s]的部署方式!\n", profile.Framework)
    }
}
